import { ICtrlService, IHttpResponse, IParam } from '@/core/interface';
import { deepCopy, mergeViewParams, transformDoData } from '@/core/utils';
import { ControlVOBase } from '../control-vo';

/**
 * 部件服务基类
 *
 * @export
 * @class CtrlServiceBase
 * @template T
 */
export class CtrlServiceBase<T extends ControlVOBase>
	implements ICtrlService<T>
{
	/**
	 * 实体服务
	 *
	 * @type {*}
	 * @memberof GridService
	 */
	protected appEntityService: any;

	/**
	 * Creates an instance of CtrlServiceBase.
	 * @param {new (data: any) => T} controlVOType
	 * @memberof CtrlServiceBase
	 */
	constructor(
		private controlVOType: new (data: any) => T,
		private entityCodeName: string,
		opts?: IParam
	) {
		this.initEntityService();
	}

	/**
	 * 初始化实体服务
	 *
	 * @protected
	 * @return {*}  {Promise<void>}
	 * @memberof CtrlServiceBase
	 */
	protected async initEntityService(): Promise<void> {
		if (this.appEntityService) {
			return;
		}
		try {
			this.appEntityService = await App.getDataService(this.entityCodeName);
		} catch (error) {
			console.error('获取实体服务异常', error);
		}
	}

	/**
	 * 新建部件界面数据对象
	 * @param $DO 后台数据对象
	 * @return {*}
	 */
	public newControlVO($DO: any) {
		return new this.controlVOType($DO);
	}

	/**
	 * 请求前处理函数
	 *
	 * @param {*} context
	 * @param {*} data
	 * @param {*} [opts={}]
	 * @return {*}
	 * @memberof CtrlServiceBase
	 */
	public handleRequestData(context: any, data: any, opts: any = {}) {
		const tempContext: any = JSON.parse(JSON.stringify(context));
		if (tempContext && tempContext.srfsessionid) {
			tempContext.srfsessionkey = tempContext.srfsessionid;
			delete tempContext.srfsessionid;
		}
		const _data = transformDoData<IParam>(data);
		if (data.viewParams && Object.keys(data.viewParams).length > 0) {
			mergeViewParams(_data, data.viewParams);
			delete _data.viewParams;
		}
		return { context: tempContext, data: _data };
	}

	/**
	 * 请求后处理函数
	 *
	 * @param {*} response
	 * @param {*} [opts={}]
	 * @return {*}
	 * @memberof CtrlServiceBase
	 */
	public handleResponse(response: IHttpResponse, opts: any = {}) {
		return response;
	}

	/**
	 * 前台逻辑
	 *
	 * @param {string} action
	 * @param {IParam} [context={}]
	 * @param {IParam} [data={}]
	 * @return {*}  {Promise<IHttpResponse>}
	 * @memberof CtrlServiceBase
	 */
	async frontLogic(
		action: string,
		context: IParam = {},
		data: IParam = {}
	): Promise<IHttpResponse> {
		throw new Error('Method is not implenments');
	}
}
